/*******************************************************************************
**
** Copyright (c) 2011 - The OWE Team
**
** This file is part of OWE.
**
** OWE is a free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; version
** version 2.1 of the License.
**
** OWE is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with OWE. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/

#include <tut/tut.hpp>
#include <tut/tut_console_reporter.hpp>

#include <owe/element.h>
#include <owe/featureelement.h>
#include <owe/paramelement.h>
#include <owe/ustring.h>

#include "utests.h"

OWE_USE_NAMESPACE

namespace tut
{
    test_runner_singleton runner;

    struct FeatureElement_data {};

    typedef test_group<FeatureElement_data> testgroup;
    testgroup shared_ptr_group("FeatureElement");
    typedef testgroup::object testobject;

    template<>
    template<>
    void testobject::test<1>() {
        set_test_name("UString FeatureElement::name() const");

        FeatureElement *element;

        FakeNode feature1("feature");
        element = static_cast<FeatureElement *>(Element::fromNode(&feature1));
        ensure(element->isValid() == false);
        delete element;

        FakeNode feature2("feature");
        feature2.addAttribute("name", "GPS");
        element = static_cast<FeatureElement *>(Element::fromNode(&feature2));
        ensure(element->name() == "GPS");
        ensure(element->isValid() == true);
        ensure(element->required() == "true");
        delete element;

        FakeNode feature3("feature");
        feature3.addAttribute("name", "Maps");
        feature3.addAttribute("required", "false");
        element = static_cast<FeatureElement *>(Element::fromNode(&feature3));
        ensure(element->name() == "Maps");
        ensure(element->isValid() == true);
        ensure(element->required() == "false");
        delete element;
    }

    template<>
    template<>
    void testobject::test<2>() {
        set_test_name("const ParamElementList FeatureElement::param() const");

        FeatureElement *featureElement;
        ParamElement *paramElement1;
        ParamElement *paramElement2;
        ParamElement *paramElement3;

        FakeNode feature("feature");
        feature.addAttribute("name", "GPS");
        featureElement = static_cast<FeatureElement *>(Element::fromNode(&feature));
        ensure(featureElement->isValid() == true);

        FakeNode param1("param");
        param1.addAttribute("name", "test1");
        param1.addAttribute("value", "123");
        paramElement1 = static_cast<ParamElement *>(Element::fromNode(&param1));
        ensure(paramElement1->isValid() == true);
        ensure(featureElement->addChild(paramElement1) == true);

        FakeNode param2("param");
        param2.addAttribute("name", "test2");
        param2.addAttribute("value", "321");
        paramElement2 = static_cast<ParamElement *>(Element::fromNode(&param2));
        ensure(paramElement2->isValid() == true);
        ensure(featureElement->addChild(paramElement2) == true);

        FakeNode param3("param");
        param3.addAttribute("name", "invalid");
        paramElement3 = static_cast<ParamElement *>(Element::fromNode(&param3));
        ensure(paramElement3->isValid() == false);
        ensure(featureElement->addChild(paramElement3) == false);

        FakeNode text("text", "some text");
        paramElement3 = static_cast<ParamElement *>(Element::fromNode(&param3));
        ensure(paramElement3->isValid() == false);
        ensure(featureElement->addChild(paramElement3) == false);

        const ParamElementList list = featureElement->param();
        ensure(list.size() == 2);

        ParamElementList::const_iterator it = list.begin();
        ensure(it->second == paramElement1);
        it++;
        ensure(it->second == paramElement2);
        it++;
        ensure(it == list.end());

        delete featureElement;
    }
}

int main(void)
{
    tut::console_reporter reporter;
    tut::runner.get().set_callback(&reporter);
    tut::runner.get().run_tests();

    return reporter.all_ok() ? 0 : 1;
}
